package com.sisgesbyte.web.managedBean.seguridad;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.StringTokenizer;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.sisgesbyte.common.ConstantesInternasSistema;
import com.sisgesbyte.services.sistema.AccesoSistema;
import com.sisgesbyte.services.sistema.bean.ValidaAccesoRequest;
import com.sisgesbyte.services.sistema.bean.ValidaAccesoResponse;

@ManagedBean
@RequestScoped
public class LoginAccesoMBean implements Serializable {

	private static final long serialVersionUID = 1L;
	private String usuario;
	private String clave;
	private String message;
	private boolean logeado = false;
	private String latLng;
	private double lat;
	private double lng;
	private String city;
	private String pais;
	private String cityCountry;
	private String navegador;
	private String tipoHost;
	private String marcaHost;
	private String idTransaccion;


	@EJB
	private AccesoSistema accesoSistema;
	
	public LoginAccesoMBean() {

	}
	public String getUsuario() {
		return usuario;
	}

	public void setUsuario(String usuario) {
		this.usuario = usuario;
	}

	public String getClave() {
		return clave;
	}

	public void setClave(String clave) {
		this.clave = clave;
	}

	public boolean isLogeado() {
		return logeado;
	}

	public void setLogeado(boolean logeado) {
		this.logeado = logeado;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public String getLatLng() {
		return latLng;
	}

	public void setLatLng(String latLng) {
		this.latLng = latLng;
	}

	public String getCityCountry() {
		return cityCountry;
	}

	public void setCityCountry(String cityCountry) {
		this.cityCountry = cityCountry;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getPais() {
		return pais;
	}

	public void setPais(String pais) {
		this.pais = pais;
	}

	public String getNavegador() {
		return navegador;
	}

	public void setNavegador(String navegador) {
		this.navegador = navegador;
	}

	public String getTipoHost() {
		return tipoHost;
	}

	public void setTipoHost(String tipoHost) {
		this.tipoHost = tipoHost;
	}
	
	public String getMarcaHost() {
		return marcaHost;
	}

	public void setMarcaHost(String marcaHost) {
		this.marcaHost = marcaHost;
	}
	
	public String getIdTransaccion() {
		return idTransaccion;
	}

	public void setIdTransaccion(String idTransaccion) {
		this.idTransaccion = idTransaccion;
	}
	
	public double getLat() {
		return lat;
	}

	public void setLat(double lat) {
		this.lat = lat;
	}

	public double getLng() {
		return lng;
	}

	public void setLng(double lng) {
		this.lng = lng;
	}

	public List<String> obtenerHost() {

		List<String> macs = new ArrayList<String>();
		try {
			Enumeration<NetworkInterface> networks = NetworkInterface
					.getNetworkInterfaces();
			while (networks.hasMoreElements()) {
				NetworkInterface network = networks.nextElement();
				byte[] mac = network.getHardwareAddress();

				if (mac != null) {

					StringBuilder sb = new StringBuilder();
					for (int i = 0; i < mac.length; i++) {
						sb.append(String.format("%02X%s", mac[i],
								(i < mac.length - 1) ? "-" : ""));
					}
					if (!macs.contains(sb.toString())) {
						macs.add(sb.toString());
					}
				}
			}
		} catch (Exception e) {
			System.out.println("Error al obtener MAC");
		}

		return macs;
	}

	public String getIPPublica() {
		String ip = "Error";
		try {
			URL whatismyip = new URL("http://checkip.amazonaws.com");
			BufferedReader in = new BufferedReader(new InputStreamReader(
					whatismyip.openStream()));
			ip = in.readLine();
		} catch (Exception e) {
			System.out.println("Error al obtener IP ");
		}
		return ip;
	}

	public String getIpPrivada() {
		InetAddress ip = null;
		try {
			ip = InetAddress.getLocalHost();
		} catch (Exception e) {
			System.out.println("Error al Obtener ip privado");
		}

		return ip.getHostAddress();
	}

	public String urlLogin(HttpServletRequest req) {

		String scheme = req.getScheme();
		String serverName = req.getServerName();
		int serverPort = req.getServerPort();
		String contextPath = req.getContextPath();
		String pagLogin = ConstantesInternasSistema.PAGINA_LOGIN;
		StringBuffer url = new StringBuffer();
		url.append(scheme).append("://").append(serverName);
		if ((serverPort != 80) && (serverPort != 443)) {
			url.append(":").append(serverPort);
		}
		url.append(contextPath).append(pagLogin);

		return url.toString();
	}

	public void obtenerLatLng(){
		try{
			String strDatos=getLatLng();
			StringTokenizer tokens=new StringTokenizer(strDatos, ";");
		        int nDatos=tokens.countTokens();
		        double[] datos=new double[nDatos];
		        int i=0;
		        while(tokens.hasMoreTokens()){
		            String str=tokens.nextToken();
		            datos[i]=Double.valueOf(str).doubleValue();
		            i++;
		        }
		        if (datos.length == 2){
		        	setLat(datos[0]);
		        	setLng(datos[1]);
		        }
		}catch(Exception e){
			System.out.println("Error al obtener Ubicacion");
		}	
	}
	public void login() {

		try {
			Boolean userActivo = true;
			String Pais = "Error";
			String Ciudad ="Error";
			setIdTransaccion(ObtenerIdTransaccion());
			obtenerLatLng();
			HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
			FacesContext context = FacesContext.getCurrentInstance();
			ArrayList<String> lsGeolocalizacion = new ArrayList<String>();
			ValidaAccesoRequest parameter = new ValidaAccesoRequest();
			parameter.setIdTransaccion(getIdTransaccion());
			parameter.setCodEmpresa(Integer.valueOf(ConstantesInternasSistema.CODIGO_EMPRESA));
			parameter.setUsuario(usuario);
			parameter.setClave(clave);
			
			StringTokenizer st = new StringTokenizer(cityCountry,";");
		     while (st.hasMoreTokens()) {
		    	 lsGeolocalizacion.add(st.nextToken());
		    }
		     try{
		    	 if((lsGeolocalizacion.size() -2) > 0){
				    	Pais = lsGeolocalizacion.get(lsGeolocalizacion.size() -2).replace("Ãº", "u");
				  }
		    	 if((lsGeolocalizacion.size() -3) > 0){
				    	Ciudad = lsGeolocalizacion.get(lsGeolocalizacion.size() -3);
				  }
		     }catch(Exception e){
		    	 System.out.println("Error al obtener Pais");
		     }
		   
		    parameter.setContinente("America");
		    parameter.setPais(Pais);
		    parameter.setRegion("Region");
		    parameter.setCiudad(Ciudad);
		    parameter.setTipoHost(getTipoHost());
		    parameter.setMarcaHost(getMarcaHost());
		    parameter.setNavegador(getNavegador());
		    parameter.setMacCliente(obtenerHost().get(0));
		    parameter.setIpPublicaCliente(getIPPublica());
		    parameter.setIpPrivadaCliente(getIpPrivada());
		    parameter.setLat(getLat());
		    parameter.setLng(getLng());
		    parameter.setActive(userActivo);
			ValidaAccesoResponse responseUsuario = accesoSistema.validarAccesoUsuario(parameter);

			if (usuario != null && responseUsuario.getCodigoRespuesta().equals("0")) {
				System.out.println("Ingreso Correctamente");
				logeado = true;
				context.getExternalContext().getSessionMap().put("usuario", usuario);
				context.getExternalContext().getSessionMap().put("codRol", responseUsuario.getCodRol());
				context.getExternalContext().getSessionMap().put("codUsuario", responseUsuario.getCodUsuario());
				context.getExternalContext().getSessionMap().put("nombreRol", responseUsuario.getNomRol());
				context.getExternalContext().getSessionMap().put("codSession", ObtenerIdTransaccion());
				
			} else {
				setMessage(ConstantesInternasSistema.ACCESO_DENEGADO);
				System.out.println("Error "+responseUsuario.getMensajeRespuesta());
				logeado = false;
			}

			if (logeado) {
				try {
					context.getExternalContext().redirect(urlLogin(req));
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			System.out.println("Error LoginAccesoMBean: " + e.getMessage());
		}
	}
	
	public String ObtenerIdTransaccion(){
		
		FacesContext fCtx = FacesContext.getCurrentInstance();
		HttpSession session = (HttpSession) fCtx.getExternalContext().getSession(false);
		String sessionId = session.getId().replace(".undefined", "");
				
		return sessionId;
	}
}
